1   /*                        __    __  __  __    __  ___
2    *                       \  \  /  /    \  \  /  /  __/
3    *                        \  \/  /  /\  \  \/  /  /
4    *                         \____/__/  \__\____/__/.ɪᴏ
5    * ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ
6    */
7   package io.vavr.collection;
8   
9   import io.vavr.*;
10  import io.vavr.control.Option;
11  
12  import java.io.Serializable;
13  import java.util.ArrayList;
14  import java.util.Comparator;
15  import java.util.NoSuchElementException;
16  import java.util.Objects;
17  import java.util.function.*;
18  import java.util.stream.Collector;
19  
20  /**
21   * SortedSet implementation, backed by a Red/Black Tree.
22   *
23   * @param <T> Component type
24   * @author Daniel Dietrich
25   */
26  // DEV-NOTE: it is not possible to create an EMPTY TreeSet without a Comparator type in scope
27  public final class TreeSet<T> implements SortedSet<T>, Serializable {
28  
29      private static final long serialVersionUID = 1L;
30  
31      private final RedBlackTree<T> tree;
32  
33      TreeSet(RedBlackTree<T> tree) {
34          this.tree = tree;
35      }
36  
37      /**
38       * Returns a {@link java.util.stream.Collector} which may be used in conjunction with
39       * {@link java.util.stream.Stream#collect(java.util.stream.Collector)} to obtain a {@link TreeSet}.
40       * <p>
41       * The natural comparator is used to compare TreeSet elements.
42       *
43       * @param <T> Component type of the List.
44       * @return A io.vavr.collection.List Collector.
45       */
46      public static <T extends Comparable<? super T>> Collector<T, ArrayList<T>, TreeSet<T>> collector() {
47          return collector(Comparators.naturalComparator());
48      }
49  
50      /**
51       * Returns a {@link java.util.stream.Collector} which may be used in conjunction with
52       * {@link java.util.stream.Stream#collect(java.util.stream.Collector)} to obtain a {@link TreeSet}.
53       *
54       * @param <T>        Component type of the List.
55       * @param comparator An element comparator
56       * @return A io.vavr.collection.List Collector.
57       */
58      public static <T> Collector<T, ArrayList<T>, TreeSet<T>> collector(Comparator<? super T> comparator) {
59          Objects.requireNonNull(comparator, "comparator is null");
60          final Supplier<ArrayList<T>> supplier = ArrayList::new;
61          final BiConsumer<ArrayList<T>, T> accumulator = ArrayList::add;
62          final BinaryOperator<ArrayList<T>> combiner = (left, right) -> {
63              left.addAll(right);
64              return left;
65          };
66          final Function<ArrayList<T>, TreeSet<T>> finisher = list -> TreeSet.ofAll(comparator, list);
67          return Collector.of(supplier, accumulator, combiner, finisher);
68      }
69  
70      public static <T extends Comparable<? super T>> TreeSet<T> empty() {
71          return new TreeSet<>(RedBlackTree.<T> empty());
72      }
73  
74      public static <T> TreeSet<T> empty(Comparator<? super T> comparator) {
75          Objects.requireNonNull(comparator, "comparator is null");
76          return new TreeSet<>(RedBlackTree.empty(comparator));
77      }
78  
79      /**
80       * Narrows a widened {@code TreeSet<? extends T>} to {@code TreeSet<T>}
81       * by performing a type-safe cast. This is eligible because immutable/read-only
82       * collections are covariant.
83       * <p>
84       * CAUTION: The underlying {@code Comparator} might fail!
85       *
86       * @param treeSet A {@code TreeSet}.
87       * @param <T>     Component type of the {@code TreeSet}.
88       * @return the given {@code treeSet} instance as narrowed type {@code TreeSet<T>}.
89       */
90      @SuppressWarnings("unchecked")
91      public static <T> TreeSet<T> narrow(TreeSet<? extends T> treeSet) {
92          return (TreeSet<T>) treeSet;
93      }
94  
95      public static <T extends Comparable<? super T>> TreeSet<T> of(T value) {
96          return new TreeSet<>(RedBlackTree.of(value));
97      }
98  
99      public static <T> TreeSet<T> of(Comparator<? super T> comparator, T value) {
100         Objects.requireNonNull(comparator, "comparator is null");
101         return new TreeSet<>(RedBlackTree.of(comparator, value));
102     }
103 
104     @SuppressWarnings("varargs")
105     @SafeVarargs
106     public static <T extends Comparable<? super T>> TreeSet<T> of(T... values) {
107         Objects.requireNonNull(values, "values is null");
108         return new TreeSet<>(RedBlackTree.of(values));
109     }
110 
111     @SuppressWarnings("varargs")
112     @SafeVarargs
113     public static <T> TreeSet<T> of(Comparator<? super T> comparator, T... values) {
114         Objects.requireNonNull(comparator, "comparator is null");
115         Objects.requireNonNull(values, "values is null");
116         return new TreeSet<>(RedBlackTree.of(comparator, values));
117     }
118 
119     /**
120      * Returns a TreeSet containing {@code n} values of a given Function {@code f}
121      * over a range of integer values from 0 to {@code n - 1}.
122      *
123      * @param <T>        Component type of the TreeSet
124      * @param comparator The comparator used to sort the elements
125      * @param n          The number of elements in the TreeSet
126      * @param f          The Function computing element values
127      * @return A TreeSet consisting of elements {@code f(0),f(1), ..., f(n - 1)}
128      * @throws NullPointerException if {@code comparator} or {@code f} are null
129      */
130     public static <T> TreeSet<T> tabulate(Comparator<? super T> comparator, int n, Function<? super Integer, ? extends T> f) {
131         Objects.requireNonNull(comparator, "comparator is null");
132         Objects.requireNonNull(f, "f is null");
133         return Collections.tabulate(n, f, TreeSet.empty(comparator), values -> of(comparator, values));
134     }
135 
136     /**
137      * Returns a TreeSet containing {@code n} values of a given Function {@code f}
138      * over a range of integer values from 0 to {@code n - 1}.
139      * The underlying comparator is the natural comparator of T.
140      *
141      * @param <T> Component type of the TreeSet
142      * @param n   The number of elements in the TreeSet
143      * @param f   The Function computing element values
144      * @return A TreeSet consisting of elements {@code f(0),f(1), ..., f(n - 1)}
145      * @throws NullPointerException if {@code f} is null
146      */
147     public static <T extends Comparable<? super T>> TreeSet<T> tabulate(int n, Function<? super Integer, ? extends T> f) {
148         Objects.requireNonNull(f, "f is null");
149         return tabulate(Comparators.naturalComparator(), n, f);
150     }
151 
152     /**
153      * Returns a TreeSet containing {@code n} values supplied by a given Supplier {@code s}.
154      *
155      * @param <T>        Component type of the TreeSet
156      * @param comparator The comparator used to sort the elements
157      * @param n          The number of elements in the TreeSet
158      * @param s          The Supplier computing element values
159      * @return A TreeSet of size {@code n}, where each element contains the result supplied by {@code s}.
160      * @throws NullPointerException if {@code comparator} or {@code s} are null
161      */
162     public static <T> TreeSet<T> fill(Comparator<? super T> comparator, int n, Supplier<? extends T> s) {
163         Objects.requireNonNull(comparator, "comparator is null");
164         Objects.requireNonNull(s, "s is null");
165         return Collections.fill(n, s, TreeSet.empty(comparator), values -> of(comparator, values));
166     }
167 
168     /**
169      * Returns a TreeSet containing {@code n} values supplied by a given Supplier {@code s}.
170      * The underlying comparator is the natural comparator of T.
171      *
172      * @param <T> Component type of the TreeSet
173      * @param n   The number of elements in the TreeSet
174      * @param s   The Supplier computing element values
175      * @return A TreeSet of size {@code n}, where each element contains the result supplied by {@code s}.
176      * @throws NullPointerException if {@code s} is null
177      */
178     public static <T extends Comparable<? super T>> TreeSet<T> fill(int n, Supplier<? extends T> s) {
179         Objects.requireNonNull(s, "s is null");
180         return fill(Comparators.naturalComparator(), n, s);
181     }
182 
183     @SuppressWarnings("unchecked")
184     public static <T extends Comparable<? super T>> TreeSet<T> ofAll(Iterable<? extends T> values) {
185         Objects.requireNonNull(values, "values is null");
186         if (values instanceof TreeSet) {
187             return (TreeSet<T>) values;
188         } else {
189             return values.iterator().hasNext() ? new TreeSet<>(RedBlackTree.ofAll(values)) : empty();
190         }
191     }
192 
193     @SuppressWarnings("unchecked")
194     public static <T> TreeSet<T> ofAll(Comparator<? super T> comparator, Iterable<? extends T> values) {
195         Objects.requireNonNull(comparator, "comparator is null");
196         Objects.requireNonNull(values, "values is null");
197         if (values instanceof TreeSet && ((TreeSet) values).comparator() == comparator) {
198             return (TreeSet<T>) values;
199         } else {
200             return values.iterator().hasNext()
201                    ? new TreeSet<>(RedBlackTree.ofAll(comparator, values))
202                    : (TreeSet<T>) empty();
203         }
204     }
205 
206     public static <T extends Comparable<? super T>> TreeSet<T> ofAll(java.util.stream.Stream<? extends T> javaStream) {
207         Objects.requireNonNull(javaStream, "javaStream is null");
208         return ofAll(Iterator.ofAll(javaStream.iterator()));
209     }
210 
211     public static <T> TreeSet<T> ofAll(Comparator<? super T> comparator, java.util.stream.Stream<? extends T> javaStream) {
212         Objects.requireNonNull(javaStream, "javaStream is null");
213         return ofAll(comparator, Iterator.ofAll(javaStream.iterator()));
214     }
215 
216     /**
217      * Creates a TreeSet from boolean values.
218      *
219      * @param elements boolean values
220      * @return A new TreeSet of Boolean values
221      * @throws NullPointerException if elements is null
222      */
223     public static TreeSet<Boolean> ofAll(boolean... elements) {
224         Objects.requireNonNull(elements, "elements is null");
225         return TreeSet.ofAll(Iterator.ofAll(elements));
226     }
227 
228     /**
229      * Creates a TreeSet from byte values.
230      *
231      * @param elements byte values
232      * @return A new TreeSet of Byte values
233      * @throws NullPointerException if elements is null
234      */
235     public static TreeSet<Byte> ofAll(byte... elements) {
236         Objects.requireNonNull(elements, "elements is null");
237         return TreeSet.ofAll(Iterator.ofAll(elements));
238     }
239 
240     /**
241      * Creates a TreeSet from char values.
242      *
243      * @param elements char values
244      * @return A new TreeSet of Character values
245      * @throws NullPointerException if elements is null
246      */
247     public static TreeSet<Character> ofAll(char... elements) {
248         Objects.requireNonNull(elements, "elements is null");
249         return TreeSet.ofAll(Iterator.ofAll(elements));
250     }
251 
252     /**
253      * Creates a TreeSet from double values.
254      *
255      * @param elements double values
256      * @return A new TreeSet of Double values
257      * @throws NullPointerException if elements is null
258      */
259     public static TreeSet<Double> ofAll(double... elements) {
260         Objects.requireNonNull(elements, "elements is null");
261         return TreeSet.ofAll(Iterator.ofAll(elements));
262     }
263 
264     /**
265      * Creates a TreeSet from float values.
266      *
267      * @param elements float values
268      * @return A new TreeSet of Float values
269      * @throws NullPointerException if elements is null
270      */
271     public static TreeSet<Float> ofAll(float... elements) {
272         Objects.requireNonNull(elements, "elements is null");
273         return TreeSet.ofAll(Iterator.ofAll(elements));
274     }
275 
276     /**
277      * Creates a TreeSet from int values.
278      *
279      * @param elements int values
280      * @return A new TreeSet of Integer values
281      * @throws NullPointerException if elements is null
282      */
283     public static TreeSet<Integer> ofAll(int... elements) {
284         Objects.requireNonNull(elements, "elements is null");
285         return TreeSet.ofAll(Iterator.ofAll(elements));
286     }
287 
288     /**
289      * Creates a TreeSet from long values.
290      *
291      * @param elements long values
292      * @return A new TreeSet of Long values
293      * @throws NullPointerException if elements is null
294      */
295     public static TreeSet<Long> ofAll(long... elements) {
296         Objects.requireNonNull(elements, "elements is null");
297         return TreeSet.ofAll(Iterator.ofAll(elements));
298     }
299 
300     /**
301      * Creates a TreeSet from short values.
302      *
303      * @param elements short values
304      * @return A new TreeSet of Short values
305      * @throws NullPointerException if elements is null
306      */
307     public static TreeSet<Short> ofAll(short... elements) {
308         Objects.requireNonNull(elements, "elements is null");
309         return TreeSet.ofAll(Iterator.ofAll(elements));
310     }
311 
312     /**
313      * Creates a TreeSet of int numbers starting from {@code from}, extending to {@code toExclusive - 1}.
314      * <p>
315      * Examples:
316      * <pre>
317      * <code>
318      * TreeSet.range(0, 0)  // = TreeSet()
319      * TreeSet.range(2, 0)  // = TreeSet()
320      * TreeSet.range(-2, 2) // = TreeSet(-2, -1, 0, 1)
321      * </code>
322      * </pre>
323      *
324      * @param from        the first number
325      * @param toExclusive the last number + 1
326      * @return a range of int values as specified or the empty range if {@code from >= toExclusive}
327      */
328     public static TreeSet<Integer> range(int from, int toExclusive) {
329         return TreeSet.ofAll(Iterator.range(from, toExclusive));
330     }
331 
332     public static TreeSet<Character> range(char from, char toExclusive) {
333         return TreeSet.ofAll(Iterator.range(from, toExclusive));
334     }
335 
336     /**
337      * Creates a TreeSet of int numbers starting from {@code from}, extending to {@code toExclusive - 1},
338      * with {@code step}.
339      * <p>
340      * Examples:
341      * <pre>
342      * <code>
343      * TreeSet.rangeBy(1, 3, 1)  // = TreeSet(1, 2)
344      * TreeSet.rangeBy(1, 4, 2)  // = TreeSet(1, 3)
345      * TreeSet.rangeBy(4, 1, -2) // = TreeSet(4, 2)
346      * TreeSet.rangeBy(4, 1, 2)  // = TreeSet()
347      * </code>
348      * </pre>
349      *
350      * @param from        the first number
351      * @param toExclusive the last number + 1
352      * @param step        the step
353      * @return a range of long values as specified or the empty range if<br>
354      * {@code from >= toInclusive} and {@code step > 0} or<br>
355      * {@code from <= toInclusive} and {@code step < 0}
356      * @throws IllegalArgumentException if {@code step} is zero
357      */
358     public static TreeSet<Integer> rangeBy(int from, int toExclusive, int step) {
359         return TreeSet.ofAll(Iterator.rangeBy(from, toExclusive, step));
360     }
361 
362     public static TreeSet<Character> rangeBy(char from, char toExclusive, int step) {
363         return TreeSet.ofAll(Iterator.rangeBy(from, toExclusive, step));
364     }
365 
366     @GwtIncompatible
367     public static TreeSet<Double> rangeBy(double from, double toExclusive, double step) {
368         return TreeSet.ofAll(Iterator.rangeBy(from, toExclusive, step));
369     }
370 
371     /**
372      * Creates a TreeSet of long numbers starting from {@code from}, extending to {@code toExclusive - 1}.
373      * <p>
374      * Examples:
375      * <pre>
376      * <code>
377      * TreeSet.range(0L, 0L)  // = TreeSet()
378      * TreeSet.range(2L, 0L)  // = TreeSet()
379      * TreeSet.range(-2L, 2L) // = TreeSet(-2L, -1L, 0L, 1L)
380      * </code>
381      * </pre>
382      *
383      * @param from        the first number
384      * @param toExclusive the last number + 1
385      * @return a range of long values as specified or the empty range if {@code from >= toExclusive}
386      */
387     public static TreeSet<Long> range(long from, long toExclusive) {
388         return TreeSet.ofAll(Iterator.range(from, toExclusive));
389     }
390 
391     /**
392      * Creates a TreeSet of long numbers starting from {@code from}, extending to {@code toExclusive - 1},
393      * with {@code step}.
394      * <p>
395      * Examples:
396      * <pre>
397      * <code>
398      * TreeSet.rangeBy(1L, 3L, 1L)  // = TreeSet(1L, 2L)
399      * TreeSet.rangeBy(1L, 4L, 2L)  // = TreeSet(1L, 3L)
400      * TreeSet.rangeBy(4L, 1L, -2L) // = TreeSet(4L, 2L)
401      * TreeSet.rangeBy(4L, 1L, 2L)  // = TreeSet()
402      * </code>
403      * </pre>
404      *
405      * @param from        the first number
406      * @param toExclusive the last number + 1
407      * @param step        the step
408      * @return a range of long values as specified or the empty range if<br>
409      * {@code from >= toInclusive} and {@code step > 0} or<br>
410      * {@code from <= toInclusive} and {@code step < 0}
411      * @throws IllegalArgumentException if {@code step} is zero
412      */
413     public static TreeSet<Long> rangeBy(long from, long toExclusive, long step) {
414         return TreeSet.ofAll(Iterator.rangeBy(from, toExclusive, step));
415     }
416 
417     /**
418      * Creates a TreeSet of int numbers starting from {@code from}, extending to {@code toInclusive}.
419      * <p>
420      * Examples:
421      * <pre>
422      * <code>
423      * TreeSet.rangeClosed(0, 0)  // = TreeSet(0)
424      * TreeSet.rangeClosed(2, 0)  // = TreeSet()
425      * TreeSet.rangeClosed(-2, 2) // = TreeSet(-2, -1, 0, 1, 2)
426      * </code>
427      * </pre>
428      *
429      * @param from        the first number
430      * @param toInclusive the last number
431      * @return a range of int values as specified or the empty range if {@code from > toInclusive}
432      */
433     public static TreeSet<Integer> rangeClosed(int from, int toInclusive) {
434         return TreeSet.ofAll(Iterator.rangeClosed(from, toInclusive));
435     }
436 
437     public static TreeSet<Character> rangeClosed(char from, char toInclusive) {
438         return TreeSet.ofAll(Iterator.rangeClosed(from, toInclusive));
439     }
440 
441     /**
442      * Creates a TreeSet of int numbers starting from {@code from}, extending to {@code toInclusive},
443      * with {@code step}.
444      * <p>
445      * Examples:
446      * <pre>
447      * <code>
448      * TreeSet.rangeClosedBy(1, 3, 1)  // = TreeSet(1, 2, 3)
449      * TreeSet.rangeClosedBy(1, 4, 2)  // = TreeSet(1, 3)
450      * TreeSet.rangeClosedBy(4, 1, -2) // = TreeSet(4, 2)
451      * TreeSet.rangeClosedBy(4, 1, 2)  // = TreeSet()
452      * </code>
453      * </pre>
454      *
455      * @param from        the first number
456      * @param toInclusive the last number
457      * @param step        the step
458      * @return a range of int values as specified or the empty range if<br>
459      * {@code from > toInclusive} and {@code step > 0} or<br>
460      * {@code from < toInclusive} and {@code step < 0}
461      * @throws IllegalArgumentException if {@code step} is zero
462      */
463     public static TreeSet<Integer> rangeClosedBy(int from, int toInclusive, int step) {
464         return TreeSet.ofAll(Iterator.rangeClosedBy(from, toInclusive, step));
465     }
466 
467     public static TreeSet<Character> rangeClosedBy(char from, char toInclusive, int step) {
468         return TreeSet.ofAll(Iterator.rangeClosedBy(from, toInclusive, step));
469     }
470 
471     @GwtIncompatible
472     public static TreeSet<Double> rangeClosedBy(double from, double toInclusive, double step) {
473         return TreeSet.ofAll(Iterator.rangeClosedBy(from, toInclusive, step));
474     }
475 
476     /**
477      * Creates a TreeSet of long numbers starting from {@code from}, extending to {@code toInclusive}.
478      * <p>
479      * Examples:
480      * <pre>
481      * <code>
482      * TreeSet.rangeClosed(0L, 0L)  // = TreeSet(0L)
483      * TreeSet.rangeClosed(2L, 0L)  // = TreeSet()
484      * TreeSet.rangeClosed(-2L, 2L) // = TreeSet(-2L, -1L, 0L, 1L, 2L)
485      * </code>
486      * </pre>
487      *
488      * @param from        the first number
489      * @param toInclusive the last number
490      * @return a range of long values as specified or the empty range if {@code from > toInclusive}
491      */
492     public static TreeSet<Long> rangeClosed(long from, long toInclusive) {
493         return TreeSet.ofAll(Iterator.rangeClosed(from, toInclusive));
494     }
495 
496     /**
497      * Creates a TreeSet of long numbers starting from {@code from}, extending to {@code toInclusive},
498      * with {@code step}.
499      * <p>
500      * Examples:
501      * <pre>
502      * <code>
503      * TreeSet.rangeClosedBy(1L, 3L, 1L)  // = TreeSet(1L, 2L, 3L)
504      * TreeSet.rangeClosedBy(1L, 4L, 2L)  // = TreeSet(1L, 3L)
505      * TreeSet.rangeClosedBy(4L, 1L, -2L) // = TreeSet(4L, 2L)
506      * TreeSet.rangeClosedBy(4L, 1L, 2L)  // = TreeSet()
507      * </code>
508      * </pre>
509      *
510      * @param from        the first number
511      * @param toInclusive the last number
512      * @param step        the step
513      * @return a range of int values as specified or the empty range if<br>
514      * {@code from > toInclusive} and {@code step > 0} or<br>
515      * {@code from < toInclusive} and {@code step < 0}
516      * @throws IllegalArgumentException if {@code step} is zero
517      */
518     public static TreeSet<Long> rangeClosedBy(long from, long toInclusive, long step) {
519         return TreeSet.ofAll(Iterator.rangeClosedBy(from, toInclusive, step));
520     }
521 
522     @Override
523     public TreeSet<T> add(T element) {
524         return contains(element) ? this : new TreeSet<>(tree.insert(element));
525     }
526 
527     @Override
528     public TreeSet<T> addAll(Iterable<? extends T> elements) {
529         Objects.requireNonNull(elements, "elements is null");
530         RedBlackTree<T> that = tree;
531         for (T element : elements) {
532             if (!that.contains(element)) {
533                 that = that.insert(element);
534             }
535         }
536         if (tree == that) {
537             return this;
538         } else {
539             return new TreeSet<>(that);
540         }
541     }
542 
543     @Override
544     public <R> TreeSet<R> collect(PartialFunction<? super T, ? extends R> partialFunction) {
545         return ofAll(Comparators.naturalComparator(), iterator().<R> collect(partialFunction));
546     }
547 
548     @Override
549     public Comparator<T> comparator() {
550         return tree.comparator();
551     }
552 
553     @SuppressWarnings("unchecked")
554     @Override
555     public TreeSet<T> diff(Set<? extends T> elements) {
556         Objects.requireNonNull(elements, "elements is null");
557         if (isEmpty()) {
558             return this;
559         } else if (elements instanceof TreeSet) {
560             final TreeSet<T> that = (TreeSet<T>) elements;
561             return that.isEmpty() ? this : new TreeSet<>(tree.difference(that.tree));
562         } else {
563             return removeAll(elements);
564         }
565     }
566 
567     @Override
568     public boolean contains(T element) {
569         return tree.contains(element);
570     }
571 
572     @Override
573     public TreeSet<T> distinct() {
574         return this;
575     }
576 
577     @Override
578     public TreeSet<T> distinctBy(Comparator<? super T> comparator) {
579         Objects.requireNonNull(comparator, "comparator is null");
580         return isEmpty() ? this : TreeSet.ofAll(tree.comparator(), iterator().distinctBy(comparator));
581     }
582 
583     @Override
584     public <U> TreeSet<T> distinctBy(Function<? super T, ? extends U> keyExtractor) {
585         Objects.requireNonNull(keyExtractor, "keyExtractor is null");
586         return isEmpty() ? this : TreeSet.ofAll(tree.comparator(), iterator().distinctBy(keyExtractor));
587     }
588 
589     @Override
590     public TreeSet<T> drop(int n) {
591         if (n <= 0 || isEmpty()) {
592             return this;
593         } else if (n >= length()) {
594             return empty(tree.comparator());
595         } else {
596             return TreeSet.ofAll(tree.comparator(), iterator().drop(n));
597         }
598     }
599 
600     @Override
601     public TreeSet<T> dropRight(int n) {
602         if (n <= 0 || isEmpty()) {
603             return this;
604         } else if (n >= length()) {
605             return empty(tree.comparator());
606         } else {
607             return TreeSet.ofAll(tree.comparator(), iterator().dropRight(n));
608         }
609     }
610 
611     @Override
612     public TreeSet<T> dropUntil(Predicate<? super T> predicate) {
613         Objects.requireNonNull(predicate, "predicate is null");
614         return dropWhile(predicate.negate());
615     }
616 
617     @Override
618     public TreeSet<T> dropWhile(Predicate<? super T> predicate) {
619         Objects.requireNonNull(predicate, "predicate is null");
620         final TreeSet<T> treeSet = TreeSet.ofAll(tree.comparator(), iterator().dropWhile(predicate));
621         return (treeSet.length() == length()) ? this : treeSet;
622     }
623 
624     @Override
625     public TreeSet<T> filter(Predicate<? super T> predicate) {
626         Objects.requireNonNull(predicate, "predicate is null");
627         final TreeSet<T> treeSet = TreeSet.ofAll(tree.comparator(), iterator().filter(predicate));
628         return (treeSet.length() == length()) ? this : treeSet;
629     }
630 
631     @Override
632     public <U> TreeSet<U> flatMap(Comparator<? super U> comparator,
633             Function<? super T, ? extends Iterable<? extends U>> mapper) {
634         Objects.requireNonNull(mapper, "mapper is null");
635         return TreeSet.ofAll(comparator, iterator().flatMap(mapper));
636     }
637 
638     @Override
639     public <U> TreeSet<U> flatMap(Function<? super T, ? extends Iterable<? extends U>> mapper) {
640         return flatMap(Comparators.naturalComparator(), mapper);
641     }
642 
643     @Override
644     public <U> U foldRight(U zero, BiFunction<? super T, ? super U, ? extends U> f) {
645         Objects.requireNonNull(f, "f is null");
646         return iterator().foldRight(zero, f);
647     }
648 
649     @Override
650     public <C> Map<C, TreeSet<T>> groupBy(Function<? super T, ? extends C> classifier) {
651         return Collections.groupBy(this, classifier, elements -> ofAll(comparator(), elements));
652     }
653 
654     @Override
655     public Iterator<TreeSet<T>> grouped(int size) {
656         return sliding(size, size);
657     }
658 
659     @Override
660     public boolean hasDefiniteSize() {
661         return true;
662     }
663 
664     @Override
665     public T head() {
666         if (isEmpty()) {
667             throw new NoSuchElementException("head of empty TreeSet");
668         } else {
669             return tree.min().get();
670         }
671     }
672 
673     @Override
674     public Option<T> headOption() {
675         return tree.min();
676     }
677 
678     @Override
679     public TreeSet<T> init() {
680         if (isEmpty()) {
681             throw new UnsupportedOperationException("init of empty TreeSet");
682         } else {
683             return new TreeSet<>(tree.delete(tree.max().get()));
684         }
685     }
686 
687     @Override
688     public Option<TreeSet<T>> initOption() {
689         return isEmpty() ? Option.none() : Option.some(init());
690     }
691 
692     @SuppressWarnings("unchecked")
693     @Override
694     public TreeSet<T> intersect(Set<? extends T> elements) {
695         Objects.requireNonNull(elements, "elements is null");
696         if (isEmpty()) {
697             return this;
698         } else if (elements instanceof TreeSet) {
699             final TreeSet<T> that = (TreeSet<T>) elements;
700             return new TreeSet<>(tree.intersection(that.tree));
701         } else {
702             return retainAll(elements);
703         }
704     }
705 
706     /**
707      * A {@code TreeSet} is computed synchronously.
708      *
709      * @return false
710      */
711     @Override
712     public boolean isAsync() {
713         return false;
714     }
715 
716     @Override
717     public boolean isEmpty() {
718         return tree.isEmpty();
719     }
720 
721     /**
722      * A {@code TreeSet} is computed eagerly.
723      *
724      * @return false
725      */
726     @Override
727     public boolean isLazy() {
728         return false;
729     }
730 
731     @Override
732     public boolean isTraversableAgain() {
733         return true;
734     }
735 
736     @Override
737     public Iterator<T> iterator() {
738         return tree.iterator();
739     }
740 
741     @Override
742     public int length() {
743         return tree.size();
744     }
745 
746     @Override
747     public <U> TreeSet<U> map(Comparator<? super U> comparator, Function<? super T, ? extends U> mapper) {
748         Objects.requireNonNull(mapper, "mapper is null");
749         return TreeSet.ofAll(comparator, iterator().map(mapper));
750     }
751 
752     @Override
753     public <U> TreeSet<U> map(Function<? super T, ? extends U> mapper) {
754         return map(Comparators.naturalComparator(), mapper);
755     }
756 
757     @Override
758     public Option<T> max() {
759         return tree.max();
760     }
761 
762     @Override
763     public Option<T> min() {
764         return tree.min();
765     }
766 
767     /**
768      * Returns this {@code TreeSet} if it is nonempty,
769      * otherwise {@code TreeSet} created from iterable, using existing comparator.
770      *
771      * @param other An alternative {@code Traversable}
772      * @return this {@code TreeSet} if it is nonempty,
773      * otherwise {@code TreeSet} created from iterable, using existing comparator.
774      */
775     @Override
776     public TreeSet<T> orElse(Iterable<? extends T> other) {
777         return isEmpty() ? ofAll(tree.comparator(), other) : this;
778     }
779 
780     /**
781      * Returns this {@code TreeSet} if it is nonempty,
782      * otherwise {@code TreeSet} created from result of evaluating supplier, using existing comparator.
783      *
784      * @param supplier An alternative {@code Traversable}
785      * @return this {@code TreeSet} if it is nonempty,
786      * otherwise {@code TreeSet} created from result of evaluating supplier, using existing comparator.
787      */
788     @Override
789     public TreeSet<T> orElse(Supplier<? extends Iterable<? extends T>> supplier) {
790         return isEmpty() ? ofAll(tree.comparator(), supplier.get()) : this;
791     }
792 
793     @Override
794     public Tuple2<TreeSet<T>, TreeSet<T>> partition(Predicate<? super T> predicate) {
795         Objects.requireNonNull(predicate, "predicate is null");
796         return iterator().partition(predicate).map(i1 -> TreeSet.ofAll(tree.comparator(), i1),
797                 i2 -> TreeSet.ofAll(tree.comparator(), i2));
798     }
799 
800     @Override
801     public TreeSet<T> peek(Consumer<? super T> action) {
802         Objects.requireNonNull(action, "action is null");
803         if (!isEmpty()) {
804             action.accept(head());
805         }
806         return this;
807     }
808 
809     @Override
810     public TreeSet<T> remove(T element) {
811         return new TreeSet<>(tree.delete(element));
812     }
813 
814     @Override
815     public TreeSet<T> removeAll(Iterable<? extends T> elements) {
816         return Collections.removeAll(this, elements);
817     }
818 
819     @Override
820     public TreeSet<T> replace(T currentElement, T newElement) {
821         if (tree.contains(currentElement)) {
822             return new TreeSet<>(tree.delete(currentElement).insert(newElement));
823         } else {
824             return this;
825         }
826     }
827 
828     @Override
829     public TreeSet<T> replaceAll(T currentElement, T newElement) {
830         // a set has only one occurrence
831         return replace(currentElement, newElement);
832     }
833 
834     @Override
835     public TreeSet<T> retainAll(Iterable<? extends T> elements) {
836         return Collections.retainAll(this, elements);
837     }
838 
839     @Override
840     public TreeSet<T> scan(T zero, BiFunction<? super T, ? super T, ? extends T> operation) {
841         return Collections.scanLeft(this, zero, operation, iter -> TreeSet.ofAll(comparator(), iter));
842     }
843 
844     @Override
845     public <U> Set<U> scanLeft(U zero, BiFunction<? super U, ? super T, ? extends U> operation) {
846         if (zero instanceof Comparable) {
847             final Comparator<U> comparator = Comparators.naturalComparator();
848             return Collections.scanLeft(this, zero, operation, iter -> TreeSet.ofAll(comparator, iter));
849         } else {
850             return Collections.scanLeft(this, zero, operation, HashSet::ofAll);
851         }
852     }
853 
854     @Override
855     public <U> Set<U> scanRight(U zero, BiFunction<? super T, ? super U, ? extends U> operation) {
856         if (zero instanceof Comparable) {
857             final Comparator<U> comparator = Comparators.naturalComparator();
858             return Collections.scanRight(this, zero, operation, iter -> TreeSet.ofAll(comparator, iter));
859         } else {
860             return Collections.scanRight(this, zero, operation, HashSet::ofAll);
861         }
862     }
863 
864     @Override
865     public Iterator<TreeSet<T>> slideBy(Function<? super T, ?> classifier) {
866         return iterator().slideBy(classifier).map(seq -> TreeSet.ofAll(tree.comparator(), seq));
867     }
868 
869     @Override
870     public Iterator<TreeSet<T>> sliding(int size) {
871         return sliding(size, 1);
872     }
873 
874     @Override
875     public Iterator<TreeSet<T>> sliding(int size, int step) {
876         return iterator().sliding(size, step).map(seq -> TreeSet.ofAll(tree.comparator(), seq));
877     }
878 
879     @Override
880     public Tuple2<TreeSet<T>, TreeSet<T>> span(Predicate<? super T> predicate) {
881         Objects.requireNonNull(predicate, "predicate is null");
882         return iterator().span(predicate).map(i1 -> TreeSet.ofAll(tree.comparator(), i1),
883                 i2 -> TreeSet.ofAll(tree.comparator(), i2));
884     }
885 
886     @Override
887     public TreeSet<T> tail() {
888         if (isEmpty()) {
889             throw new UnsupportedOperationException("tail of empty TreeSet");
890         } else {
891             return new TreeSet<>(tree.delete(tree.min().get()));
892         }
893     }
894 
895     @Override
896     public Option<TreeSet<T>> tailOption() {
897         return isEmpty() ? Option.none() : Option.some(tail());
898     }
899 
900     @Override
901     public TreeSet<T> take(int n) {
902         if (n <= 0) {
903             return empty(tree.comparator());
904         } else if (n >= length()) {
905             return this;
906         } else {
907             return TreeSet.ofAll(tree.comparator(), iterator().take(n));
908         }
909     }
910 
911     @Override
912     public TreeSet<T> takeRight(int n) {
913         if (n <= 0) {
914             return empty(tree.comparator());
915         } else if (n >= length()) {
916             return this;
917         } else {
918             return TreeSet.ofAll(tree.comparator(), iterator().takeRight(n));
919         }
920     }
921 
922     @Override
923     public TreeSet<T> takeUntil(Predicate<? super T> predicate) {
924         Objects.requireNonNull(predicate, "predicate is null");
925         final TreeSet<T> treeSet = takeWhile(predicate.negate());
926         return (treeSet.length() == length()) ? this : treeSet;
927     }
928 
929     @Override
930     public TreeSet<T> takeWhile(Predicate<? super T> predicate) {
931         Objects.requireNonNull(predicate, "predicate is null");
932         final TreeSet<T> treeSet = TreeSet.ofAll(tree.comparator(), iterator().takeWhile(predicate));
933         return (treeSet.length() == length()) ? this : treeSet;
934     }
935 
936     /**
937      * Transforms this {@code TreeSet}.
938      *
939      * @param f   A transformation
940      * @param <U> Type of transformation result
941      * @return An instance of type {@code U}
942      * @throws NullPointerException if {@code f} is null
943      */
944     public <U> U transform(Function<? super TreeSet<T>, ? extends U> f) {
945         Objects.requireNonNull(f, "f is null");
946         return f.apply(this);
947     }
948 
949     @Override
950     public java.util.TreeSet<T> toJavaSet() {
951         return toJavaSet(ignore -> new java.util.TreeSet<>(comparator()));
952     }
953 
954     @SuppressWarnings("unchecked")
955     @Override
956     public TreeSet<T> union(Set<? extends T> elements) {
957         Objects.requireNonNull(elements, "elements is null");
958         if (elements instanceof TreeSet) {
959             final TreeSet<T> that = (TreeSet<T>) elements;
960             return that.isEmpty() ? this : new TreeSet<>(tree.union(that.tree));
961         } else {
962             return addAll(elements);
963         }
964     }
965 
966     @Override
967     public <T1, T2> Tuple2<TreeSet<T1>, TreeSet<T2>> unzip(
968             Function<? super T, Tuple2<? extends T1, ? extends T2>> unzipper) {
969         Objects.requireNonNull(unzipper, "unzipper is null");
970         return iterator().unzip(unzipper).map(i1 -> TreeSet.ofAll(Comparators.naturalComparator(), i1),
971                 i2 -> TreeSet.ofAll(Comparators.naturalComparator(), i2));
972     }
973 
974     @Override
975     public <T1, T2, T3> Tuple3<TreeSet<T1>, TreeSet<T2>, TreeSet<T3>> unzip3(
976             Function<? super T, Tuple3<? extends T1, ? extends T2, ? extends T3>> unzipper) {
977         Objects.requireNonNull(unzipper, "unzipper is null");
978         return iterator().unzip3(unzipper).map(
979                 i1 -> TreeSet.ofAll(Comparators.naturalComparator(), i1),
980                 i2 -> TreeSet.ofAll(Comparators.naturalComparator(), i2),
981                 i3 -> TreeSet.ofAll(Comparators.naturalComparator(), i3));
982     }
983 
984     @Override
985     public <U> TreeSet<Tuple2<T, U>> zip(Iterable<? extends U> that) {
986         return zipWith(that, Tuple::of);
987     }
988 
989     @Override
990     public <U, R> TreeSet<R> zipWith(Iterable<? extends U> that, BiFunction<? super T, ? super U, ? extends R> mapper) {
991         Objects.requireNonNull(that, "that is null");
992         Objects.requireNonNull(mapper, "mapper is null");
993         return TreeSet.ofAll(Comparators.naturalComparator(), iterator().zipWith(that, mapper));
994     }
995 
996     @Override
997     public <U> TreeSet<Tuple2<T, U>> zipAll(Iterable<? extends U> that, T thisElem, U thatElem) {
998         Objects.requireNonNull(that, "that is null");
999         final Comparator<Tuple2<T, U>> tuple2Comparator = Tuple2.comparator(tree.comparator(), Comparators.naturalComparator());
1000         return TreeSet.ofAll(tuple2Comparator, iterator().zipAll(that, thisElem, thatElem));
1001     }
1002 
1003     @Override
1004     public TreeSet<Tuple2<T, Integer>> zipWithIndex() {
1005         final Comparator<? super T> component1Comparator = tree.comparator();
1006         final Comparator<Tuple2<T, Integer>> tuple2Comparator = (t1, t2) -> component1Comparator.compare(t1._1, t2._1);
1007         return TreeSet.ofAll(tuple2Comparator, iterator().zipWithIndex());
1008     }
1009 
1010     @Override
1011     public <U> SortedSet<U> zipWithIndex(BiFunction<? super T, ? super Integer, ? extends U> mapper) {
1012         return TreeSet.ofAll(Comparators.naturalComparator(), iterator().zipWithIndex(mapper));
1013     }
1014 
1015     // -- Object
1016 
1017     @Override
1018     public boolean equals(Object o) {
1019         return Collections.equals(this, o);
1020     }
1021 
1022     @Override
1023     public int hashCode() {
1024         return Collections.hashUnordered(this);
1025     }
1026 
1027     @Override
1028     public String stringPrefix() {
1029         return "TreeSet";
1030     }
1031 
1032     @Override
1033     public String toString() {
1034         return mkString(stringPrefix() + "(", ", ", ")");
1035     }
1036 }